home *** CD-ROM | disk | FTP | other *** search
/ PC World 2006 November / PCWorld_2006-11_cd.bin / domacnost a kancelar / findgraph / fgraph.exe / {app} / TestVC / RectItem.cpp < prev    next >
C/C++ Source or Header  |  2002-08-09  |  9KB  |  391 lines

  1. // RectItem.cpp : implementation of the CRectItem class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Crov.h"
  6.  
  7. #include "MainDoc.h"
  8. #include "MainView.h"
  9. #include "RectItem.h"
  10.  
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__; 
  15. #endif
  16.  
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CRectItem implementation
  19.  
  20. IMPLEMENT_SERIAL(CRectItem, COleClientItem, 0)
  21.  
  22. CRectItem::CRectItem(COleDocument* pContainer) : COleClientItem(pContainer) ,
  23.     m_ptPos(10, -10), m_sizeContent(0,0), m_sizeIcon(0,0),
  24.     m_sizeContentExtent(0, 0), m_sizeIconExtent(0, 0)
  25. {
  26. }
  27.  
  28. CRectItem::CRectItem(COleDocument* pContainer, int x, int y) : COleClientItem(pContainer) ,
  29.     m_sizeContent(0,0), m_sizeIcon(0,0),
  30.     m_sizeContentExtent(0, 0), m_sizeIconExtent(0, 0)
  31. {
  32.     m_ptPos.x = x;
  33.     m_ptPos.y = y;
  34. }
  35.  
  36. CRectItem::CRectItem() :
  37.     m_ptPos(10, -10), m_sizeContent(0,0), m_sizeIcon(0,0),
  38.     m_sizeContentExtent(0, 0), m_sizeIconExtent(0, 0)
  39. {
  40. }
  41.  
  42. CRectItem::~CRectItem()
  43. {
  44. }
  45. void CRectItem::Invalidate(CView* pNotThisView)
  46. {
  47.     GetDocument()->UpdateAllViews(pNotThisView, 0, this);
  48. }
  49.  
  50. /////////////////////////////////////////////////////////////////////////////
  51. // CRectItem diagnostics
  52.  
  53. #ifdef _DEBUG
  54. void CRectItem::AssertValid() const
  55. {
  56.     COleClientItem::AssertValid();
  57. }
  58.  
  59. void CRectItem::Dump(CDumpContext& dc) const
  60. {
  61.     COleClientItem::Dump(dc);
  62. }
  63. #endif
  64.  
  65.  
  66. /////////////////////////////////////////////////////////////////////////////
  67. CSize CRectItem::GetSize()
  68. {
  69.  
  70. if (!this)    return CSize(0, 0);
  71.     ASSERT_VALID(this);
  72.  
  73.     DVASPECT dv = GetDrawAspect();
  74.     if (dv == DVASPECT_ICON)
  75.         return m_sizeIcon;
  76.     else
  77.         return m_sizeContent;
  78. }
  79.  
  80. CSize CRectItem::GetBaseSize()
  81. {
  82.     DVASPECT dv = GetDrawAspect();
  83.     if (dv == DVASPECT_ICON)
  84.         return m_sizeIconExtent;
  85.     else
  86.         return m_sizeContentExtent;
  87. }
  88.  
  89. void CRectItem::SetSize(CSize size)
  90. {
  91.     DVASPECT dv = GetDrawAspect();
  92.     if (dv == DVASPECT_ICON)
  93.         m_sizeIcon = size;
  94.     else
  95.         m_sizeContent = size;
  96. }
  97.  
  98. void CRectItem::SetBaseSize(CSize size)
  99. {
  100. ASSERT_VALID(this);
  101.     DVASPECT dv = GetDrawAspect();
  102.     if (dv == DVASPECT_ICON)
  103.         m_sizeIconExtent = size;
  104.     else
  105.         m_sizeContentExtent = size;
  106. }
  107.  
  108. void CRectItem::SetRect(CRect& rect)
  109. {
  110.     m_ptPos = rect.TopLeft();
  111.     SetSize(rect.Size());
  112. }
  113.  
  114. BOOL CRectItem::UpdateExtent()
  115. {
  116.     // get size in pixels
  117.     CSize size;
  118.     if (!GetCachedExtent(&size))
  119.         return FALSE;       // blank
  120.     Invalidate();   // invalidate the old size/position
  121.     CSize sizeBase = GetBaseSize();
  122.     if (size == sizeBase) // no change
  123.         return FALSE;
  124.     // if new object (i.e. m_extent is empty) setup position
  125.     if (sizeBase == CSize(0,0))
  126.     {
  127.         // convert to document coords
  128.         CSize sizeNew(MulDiv(size.cx, 10, 254), - MulDiv(size.cy, 10, 254));
  129.         SetSize(sizeNew);
  130.     }
  131.     else
  132.     {
  133.         if (!IsInPlaceActive() && size != sizeBase)
  134.         {
  135.             // data changed and not inplace, so scale up rect as well
  136.             CSize sizeCur = GetSize();
  137.             sizeCur.cx = MulDiv(sizeCur.cx, size.cx, sizeBase.cx);
  138.             sizeCur.cy = - MulDiv(-sizeCur.cy, size.cy, sizeBase.cy);
  139.             SetSize(sizeCur);
  140.         }
  141.     }
  142.     SetBaseSize(size);
  143.     Invalidate();   // as well as the new size/position
  144.     return TRUE;
  145. }
  146.  
  147. BOOL CRectItem::OnChangeItemPosition(const CRect& rectPos)
  148. {
  149.     CMainView* pView = GetActiveView();
  150.     if (pView == NULL)
  151.         return FALSE;
  152.     ASSERT_VALID(pView);
  153.  
  154.     CRect rc = rectPos;
  155.     pView->ClientToDoc(rc);
  156.  
  157.     if (rc != GetRect())
  158.     {
  159.         // invalidate old item
  160.         Invalidate();
  161.         // update to new rectangle
  162.         SetRect(rc);
  163.  
  164.         GetDocument()->SetModifiedFlag();
  165.         CSize sizeExtent;
  166.         GetCachedExtent(&sizeExtent);
  167.         SetBaseSize(sizeExtent);
  168.  
  169.         // and invalidate new
  170.         Invalidate();
  171.     }
  172.     return COleClientItem::OnChangeItemPosition(rectPos);
  173. }
  174.  
  175. void CRectItem::OnActivate()
  176. {
  177.     // allow only one inplace active item per frame
  178.     CMainView* pView = GetActiveView();
  179.     ASSERT_VALID(pView);
  180.     COleClientItem* pItem = GetDocument()->GetInPlaceActiveItem(pView);
  181.     if (pItem != NULL && pItem != this)
  182.         pItem->Close();
  183.  
  184.     COleClientItem::OnActivate();
  185.  
  186.     // set selection to an item when it becomes active
  187.     pView->SetSelection(this);
  188. }
  189.  
  190. void CRectItem::OnDeactivateUI(BOOL bUndoable)
  191. {
  192.     COleClientItem::OnDeactivateUI(bUndoable);
  193.  
  194.     // hide the object if it is not an outside-in object
  195.     ASSERT_VALID(this);
  196.     DWORD dwMisc = 0;
  197.     m_lpObject->GetMiscStatus(GetDrawAspect(), &dwMisc);
  198.     if (dwMisc & OLEMISC_INSIDEOUT)
  199.         DoVerb(OLEIVERB_HIDE, NULL);
  200. }
  201.  
  202. void CRectItem::OnChange(OLE_NOTIFICATION nCode, DWORD dwParam)
  203. {
  204.     COleClientItem::OnChange(nCode, dwParam);
  205.     switch(nCode)
  206.     {
  207.         case OLE_CHANGED:
  208.             UpdateExtent();
  209.             Invalidate();
  210.             break;
  211.         case OLE_CHANGED_ASPECT:
  212.         case OLE_CHANGED_STATE:
  213.             Invalidate();
  214.             break;
  215.     }
  216. }
  217.  
  218. void CRectItem::OnGetItemPosition(CRect& rPosition)
  219. {
  220.     ASSERT_VALID(this);
  221.  
  222.     if (GetSize() == CSize(0,0))
  223.         UpdateExtent();
  224.  
  225.     // copy m_rect, which is in document coordinates
  226.     rPosition = GetRect();
  227.     CMainView* pView = GetActiveView();
  228.     ASSERT_VALID(pView);
  229.     pView->DocToClient(rPosition);
  230. }
  231.  
  232. void CRectItem::Move(CRect &rc)
  233. {
  234.     // invalidate old rect
  235.     Invalidate();
  236.     // invalidate new
  237.     SetRect(rc);
  238.     Invalidate();
  239.  
  240.     // update item rect when in-place active
  241.     if (IsInPlaceActive())
  242.         SetItemRects();
  243. }
  244.  
  245. void CRectItem::ResetSize()
  246. {
  247.     ASSERT_VALID(this);
  248.     Invalidate();
  249.     SetBaseSize(CSize(0, 0));
  250.     UpdateExtent();
  251. }
  252.  
  253.  
  254.  
  255.  
  256.  
  257. /////////////////////////////////////////////////////////////////////////////
  258.  
  259.  
  260. void CRectItem::Serialize(CArchive& ar)
  261. {
  262.     ASSERT_VALID(this);
  263.  
  264.     // Call base class first to read in COleClientItem data.
  265.     // Since this sets up the m_pDocument pointer returned from
  266.     //  CRectItem::GetDocument, it is a good idea to call
  267.     //  the base class Serialize first.
  268.     CRect rect;
  269.  
  270.     // IMPORTANT: when using "easy" serialize -- call base class FIRST!
  271.     //  (not strictly necessary, but a good idea)
  272.     COleClientItem::Serialize(ar);
  273.  
  274.     // now store/retrieve data specific to CRectItem
  275.     if (ar.IsStoring())
  276.     {
  277.         WORD w = 0x5500;        // magic value
  278.         ar << w << m_ptPos;
  279.         ar << m_sizeIcon << m_sizeIconExtent;
  280.         ar << m_sizeContent << m_sizeContentExtent;
  281.     }
  282.     else
  283.     {
  284.         WORD w;
  285.         ar >> w >> m_ptPos;
  286.         ar >> m_sizeIcon >> m_sizeIconExtent;
  287.         ar >> m_sizeContent >> m_sizeContentExtent;
  288.         if (w != 0x5500)
  289.         {
  290.             TRACE0("Bad magic number in front of an item wnd\n");
  291.             AfxThrowArchiveException(CArchiveException::generic);
  292.         }
  293.     }
  294. }
  295.  
  296. /////////////////////////////////////////////////////////////////////////////
  297. // OnGetClipboardData is used by CopyToClipboard and DoDragDrop
  298. COleDataSource* CRectItem::OnGetClipboardData(
  299.     BOOL bIncludeLink, LPPOINT lpOffset, LPSIZE lpSize)
  300. {
  301.     ASSERT_VALID(this);
  302.  
  303.     COleDataSource* pDataSource = new COleDataSource;
  304.     TRY
  305.     {
  306.         GetNativeClipboardData(pDataSource);
  307.         GetClipboardData(pDataSource, bIncludeLink, lpOffset, lpSize);
  308.     }
  309.     CATCH_ALL(e)
  310.     {
  311.         delete pDataSource;
  312.         THROW_LAST();
  313.     }
  314.     END_CATCH_ALL
  315.  
  316.     ASSERT_VALID(pDataSource);
  317.     return pDataSource;
  318. }
  319.  
  320. void CRectItem::GetNativeClipboardData(COleDataSource* pDataSource)
  321. {
  322.     ASSERT_VALID(this);
  323.     ASSERT_VALID(GetDocument());
  324.  
  325.     // Create a shared file and associate a CArchive with it
  326.     CSharedFile file;
  327.     CArchive ar(&file, CArchive::store);
  328.  
  329.     // Serialize selected objects to the archive
  330.     Serialize(ar);
  331.     ar.Close();
  332.     pDataSource->CacheGlobalData(CMainDoc::m_cfPrivate, file.Detach());
  333. }
  334.  
  335. /////////////////////////////////////////////////////////////////////////////
  336.  
  337. /////////////////////////////////////////////////////////////////////////////
  338. // From MSDN: HOWTO: IQ: Q184663
  339.  
  340. /*******************************************************************
  341. *   This method returns the IDispatch* for the application linked to
  342. *   this container.
  343. ********************************************************************/ 
  344. LPDISPATCH CRectItem::GetIDispatch()
  345. {
  346.    //The this and m_lpObject pointers must be valid for this function
  347.    //to work correctly. The m_lpObject is the IUnknown pointer to
  348.    // this object.
  349.    ASSERT_VALID(this);
  350.    ASSERT(m_lpObject != NULL);
  351.  
  352.    LPUNKNOWN lpUnk = m_lpObject;
  353.  
  354.    //The embedded application must be running in order for the rest
  355.    //of the function to work.
  356.    Run();
  357.  
  358.    //QI for the IOleLink interface of m_lpObject.
  359.    LPOLELINK lpOleLink = NULL;
  360.    if (m_lpObject->QueryInterface(IID_IOleLink,
  361.       (LPVOID FAR*)&lpOleLink) == NOERROR)
  362.    {
  363.       ASSERT(lpOleLink != NULL);
  364.       lpUnk = NULL;
  365.  
  366.       //Retrieve the IUnknown interface to the linked application.
  367.       if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
  368.       {
  369.          TRACE0("Warning: Link is not connected!\n");
  370.          lpOleLink->Release();
  371.          return NULL;
  372.       }
  373.       ASSERT(lpUnk != NULL);
  374.    }
  375.  
  376.    //QI for the IDispatch interface of the linked application.
  377.    LPDISPATCH lpDispatch = NULL;
  378.    if (lpUnk->QueryInterface(IID_IDispatch, (LPVOID FAR*)&lpDispatch)
  379.       !=NOERROR)
  380.    {
  381.       TRACE0("Warning: does not support IDispatch!\n");
  382.       return NULL;
  383.    }
  384.  
  385.    //After assuring ourselves it is valid, return the IDispatch
  386.    //interface to the caller.
  387.    ASSERT(lpDispatch != NULL);
  388.    return lpDispatch;
  389.  
  390.